package cn.edu.tcu.db;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;

import cn.edu.tcu.myutils.MyUtil;

public class DBDriverWithTransaction {
	// 声明线程共享变量
	private ThreadLocal<Connection> container = new ThreadLocal<Connection>();

	/**
	 * 获取当前线程上的连接 开启事务
	 */
	public void beginTransaction() {
		try {
			Connection conn = container.get();// 首先获取当前线程的连接
			if (conn == null) {// 如果连接为空
				conn = DBDataSource.getDataSource().getConnection(); // 从连接池中获取连接
				container.set(conn);// 将此连接放在当前线程上
			}
			conn.setAutoCommit(false);// 开启事务
		} catch (SQLException e) {
			System.out.println("事务处理-获取Connection对象异常：" + e.getMessage());
			e.printStackTrace();
		}
	}

	/**
	 * 提交事务
	 */
	public void commit() {
		// 从当前线程上获取连接
		Connection conn = container.get();
		// 如果连接为空，则不做处理
		if (conn != null) {
			try {
				// 提交事务
				conn.commit();
			} catch (SQLException e) {
				System.out.println("事务处理-提交事务异常：" + e.getMessage());
				e.printStackTrace();
			}
		}
	}

	/**
	 * 回滚事务
	 */
	public void rollback() {
		// 检查当前线程是否存在连接
		Connection conn = container.get();
		if (conn != null) {
			try {
				// 回滚事务
				conn.rollback();
				// 如果回滚了，就移除这个连接
				// container.remove();
			} catch (SQLException e) {
				System.out.println("事务处理-回滚事务异常：" + e.getMessage());
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭连接
	 */
	public void close() {
		Connection conn = container.get();
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				System.out.println("事务处理-关闭Connection对象异常：" + e.getMessage());
				e.printStackTrace();
			} finally {
				// 从当前线程移除连接 切记，否则该线程的连接得不到释放
				container.remove();
			}
		}
	}

	/**
	 * 使用dbutils查询数据库
	 * 
	 * @param sql
	 *            查询sql语句
	 * @param rsh
	 *            结果集类型
	 * @param params
	 *            sql语句查询参数
	 * @return 查询结果集
	 */
	public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) {
		// 返回值
		T result = null;
		// 检查当前线程是否存在连接
		Connection conn = container.get();
		if (conn != null) {
			try {
				// 创建一个查询对象 queryrunner
				QueryRunner qr = new QueryRunner(true);
				// 进行查询操作
				result = qr.query(conn, sql, rsh, params);
			} catch (SQLException e) {
				// 发生异常之后，回滚事务
				rollback();
				// dbutils查询数据库异常
				MyUtil.logRootLogger.debug("dbutils查询数据库异常：" + e.getMessage());
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * 使用dbutils新增、删除、修改数据库
	 * 
	 * @param sql
	 *            sql语句
	 * @param params
	 *            sql语句查询参数
	 * @return 新增、删除、修改数据库所影响的记录条数
	 */
	public int update(String sql, Object... params) {
		// 返回值
		int result = 0;
		// 检查当前线程是否存在连接
		Connection conn = container.get();
		if (conn != null) {
			try {
				// 创建一个查询对象 queryrunner
				QueryRunner qr = new QueryRunner(true);
				// 进行查询操作
				result = qr.update(conn, sql, params);
			} catch (SQLException e) {
				// 发生异常之后，回滚事务
				rollback();
				// dbutils查询数据库异常
				MyUtil.logRootLogger.debug("dbutils新增、删除、修改数据库异常：" + e.getMessage());
				e.printStackTrace();
			}
		}

		return result;
	}

	/**
	 * 使用dbutils新增数据库
	 * 
	 * @param sql
	 *            新增sql语句
	 * @param rsh
	 *            结果集类型
	 * @param params
	 *            sql语句新增参数
	 * @return 新增操作的结果集
	 */
	public <T> T insert(String sql, ResultSetHandler<T> rsh, Object... params) {
		// 返回值
		T result = null;
		// 检查当前线程是否存在连接
		Connection conn = container.get();
		if (conn != null) {
			try {
				// 创建一个查询对象 queryrunner
				QueryRunner qr = new QueryRunner(true);
				// 进行查询操作
				result = qr.insert(conn, sql, rsh, params);
			} catch (SQLException e) {
				// 发生异常之后，回滚事务
				rollback();
				// dbutils查询数据库异常
				MyUtil.logRootLogger.debug("dbutils新增数据库异常：" + e.getMessage());
				e.printStackTrace();
			}
		}

		return result;
	}

}
